Repository navigation
feat(io)!: registered files for compio sockets on io_uring - #153
Merged
Merged
Conversation
Each compio stream on Linux takes a slot in its ring's file table, and every operation on it (multishot and single receives, copying and zero-copy sends, readiness polls, shutdown) addresses the socket by that slot with IOSQE_FIXED_FILE, so the kernel no longer looks the descriptor up and references its file per operation. The descriptor stays for kernel TLS options, addresses and splice. The slot is allocated with IORING_OP_FILES_UPDATE on a runtime task, so no operation waits for it and none abandoned midway loses it; the first stream on a ring registers the table, sized by the new FileTable setting (runtime-adjustable, default 1024). A full table or a kernel without slot allocation leaves the stream on its descriptor; a table the kernel refuses is the stream's next error. compio builds its operations on descriptors, so an adapter rewrites the entries they build and keeps the rest of each operation, buffer-ring handling included, compio's. Compio::with_zero_copy becomes a builder method beside Compio::with_file_table. Refs #125
|
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
This was referenced Nov 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
On Linux, each compio stream now takes a slot in its ring's registered file table. Every socket operation goes through that slot, so the kernel skips the file refcount on each operation. That covers receive (multishot and single), send, vectored and zero-copy send,
write_control, the splice readiness polls and shutdown. Kernel-TLS setsockopt, address lookups and splice itself still use the plain descriptor.compio::FileTableis the table size, an operator setting shared across clones. It defaults to 1024, the kernel's default soft open-file limit. A ring sizes its table when its first stream registers, so a new size only affects rings that register later. 0 stops new streams from taking slots straight away.Compio::with_file_tableandCompio::file_tablecarry it.with_zero_copyis now a builder method too:Compio::default().with_zero_copy(..).FILES_UPDATE, so operations never wait for it, and dropping the stream gives the slot back. A full table, or a kernel older than 5.19, leaves the stream on its plain descriptor. Any other registration failure comes back as the stream's next I/O error.compio only registers a whole table at once and its own ops use the plain fd. This crate installs single slots with its own
FilesUpdateop, and swaps in the slot index by writing the SQE the same way compio'sset_poll_firstdoes.On Linux, new tests point a stream's fd at
/dev/nullafter it registers and check that reads, copying writes, zero-copy writes and shutdown still reach the peer. They also cover a one-slot table falling back for the second socket, and a table size the kernel refuses failing the stream. The io, h1 and h3 builds pass. The kTLS suites need CI.Fixed buffers are not part of this. See #125.
Part of #125